# -*- coding: UTF-8 -*-
# Author: Damon(wuud1)
# CreateDate: 
# Message:
from uuid import uuid4
from untils.requestsTools import requestsTools
import json, os, time, random, requests
from copy import deepcopy
from setting import *
from cadillac_getCookies import ToolBox

class ScSpider:

    def __init__(self, brand, cidList):
        self.brand = brand
        self.cidList = cidList
        self.brandCode= brandCodeDict[brand]
        self.basePath = os.getcwd()+os.sep+'..'+os.sep+'saicgmHtml'+os.sep+self.brand
        self.imgPath = os.getcwd()+os.sep+'..'+os.sep+'saicgmImg'+os.sep+self.brand
        if not os.path.exists(self.basePath):
            os.makedirs(self.basePath)
        if not os.path.exists(self.imgPath):
            os.makedirs(self.imgPath)
        self.resTools = requestsTools(basePath=self.basePath)

        # 登录并设置参数
        loginTools = ToolBox()
        cookiesStr, cookiesDict, currentUrl = loginTools.run(Account[brand]["username"], Account[brand]["password"])
        self.indexUrl = currentUrl.split("#")[0]
        print(cookiesDict)
        print(self.indexUrl)
        self.resTools.cookies = cookiesDict

    def get_timeStr(self, l=13):
        return str(time.time()).replace(".", "")[:l]

    def modelYears(self):
        url = 'https://dpj.saic-gm.com/epcoloe4dealer/rest/brands/2/modelYears'
        params = '?_dc={}'.format(self.get_timeStr())
        url = url + params
        self.resTools.headers = {
            "Host": "dpj.saic-gm.com",
            "Connection": "keep-alive",
            "Pragma": "no-cache",
            "Cache-Control": "no-cache",
            "Accept": "application/json, text/plain, */*",
            "x-resource-code": "catalogsselectBrand",
            "oe-version-no": "V4.0.0.1",
            "x-track-code": "{}".format(uuid4()),
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36",
            "Referer": self.indexUrl,
            "Accept-Encoding": "gzip, deflate, br",
            "Accept-Language": "zh-CN,zh;q=0.9",
        }
        self.resTools.parseUrl(url=url, fileName="modelYears")

    def grant(self):
        url = 'https://dpj.saic-gm.com/epcoloe4dealer/rest/users/button/grant/1001'
        params = '?_dc={}'.format(self.get_timeStr())
        url = url + params
        self.resTools.headers = {
            "Host": "dpj.saic-gm.com",
            "Connection": "keep-alive",
            "Pragma": "no-cache",
            "Cache-Control": "no-cache",
            "Accept": "application/json, text/plain, */*",
            "x-resource-code": "catalogsbuttonRest",
            "oe-version-no": "V4.0.0.1",
            "x-track-code": "{}".format(uuid4()),
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36",
            "Referer": self.indexUrl,
            "Accept-Encoding": "gzip, deflate, br",
            "Accept-Language": "zh-CN,zh;q=0.9",
        }
        self.resTools.parseUrl(url=url, fileName="grant")

    def _get_carList(self):
        url = 'https://dpj.saic-gm.com/epcoloe4dealer/rest/catalogs'
        params = "?_dc={}&brandCode={}&year=ALL".format(self.get_timeStr(), self.brandCode)
        url = url + params
        self.resTools.headers = {
            "Host": "dpj.saic-gm.com",
            "Connection": "keep-alive",
            "Pragma": "no-cache",
            "Cache-Control": "no-cache",
            "Accept": "application/json, text/plain, */*",
            "x-resource-code": "catalogsbuttonRest",
            "oe-version-no": "V4.0.0.1",
            "x-track-code": "{}".format(uuid4()),
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36",
            "Referer": self.indexUrl,
            "Accept-Encoding": "gzip, deflate, br",
            "Accept-Language": "zh-CN,zh;q=0.9",
        }
        resInfo = self.resTools.parseUrl(url=url, fileName=self.brand+'CarsList')
        carsInfo = json.loads(resInfo.get("content"))
        return carsInfo

    def get_groupInfo(self, cid):
        url = 'https://dpj.saic-gm.com/epcoloe4dealer/rest/catalogs/{}/groups'.format(cid)
        params = "?_dc={}&brandCode={}&year=ALL".format(self.get_timeStr(), self.brandCode)
        url = url + params
        self.resTools.headers = {
            "Host": "dpj.saic-gm.com",
            "Connection": "keep-alive",
            "Pragma": "no-cache",
            "Cache-Control": "no-cache",
            "Accept": "application/json, text/plain, */*",
            "x-resource-code": "catalogsselectCatalog",
            "oe-version-no": "V4.0.0.1",
            "x-track-code": "{}".format(uuid4()),
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36",
            "Referer": self.indexUrl,
            "Accept-Encoding": "gzip, deflate, br",
            "Accept-Language": "zh-CN,zh;q=0.9",
        }
        resInfo = self.resTools.parseUrl(url=url, fileName="groups"+cid)
        groupsInfo = json.loads(resInfo.get("content"))
        return groupsInfo

    def get_strucInfo(self, cid, groupCode):
        url = 'https://dpj.saic-gm.com/epcoloe4dealer/rest/subjects'
        params = "?_dc={}&brandCode={}&catalogCode={}&groupCode={}&year=ALL".format(self.get_timeStr(), self.brandCode, cid, groupCode)
        url = url + params
        self.resTools.headers = {
            "Host": "dpj.saic-gm.com",
            "Connection": "keep-alive",
            "Pragma": "no-cache",
            "Cache-Control": "no-cache",
            "Accept": "application/json, text/plain, */*",
            "x-resource-code": "catalogsselectGroup",
            "oe-version-no": "V4.0.0.1",
            "x-track-code": "{}".format(uuid4()),
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36",
            "Referer": self.indexUrl,
            "Accept-Encoding": "gzip, deflate, br",
            "Accept-Language": "zh-CN,zh;q=0.9",
        }
        resInfo = self.resTools.parseUrl(url=url, fileName="subjects"+cid+groupCode)
        strucsInfo = json.loads(resInfo.get("content"))
        return strucsInfo

    def get_partsInfo(self, cid, groupCode, subject, subjectId, suffix):
        url = 'https://dpj.saic-gm.com/epcoloe4dealer/rest/engineering/images/partsEngineerSubjects'
        params = "?_dc={}&brand={}&catalog={}&group={}&id=&subject={}&subjectId={}&suffix={}&vinOptionList=&year=ALL".format(self.get_timeStr(),
                                                                                                                             self.brandCode,
                                                                                                                             cid,
                                                                                                                             groupCode,
                                                                                                                             subject,
                                                                                                                             subjectId,
                                                                                                                             suffix)
        url = url + params
        self.resTools.headers = {
            "Host": "dpj.saic-gm.com",
            "Connection": "keep-alive",
            "Pragma": "no-cache",
            "Cache-Control": "no-cache",
            "Accept": "application/json, text/plain, */*",
            "x-resource-code": "catalogsgotoPartPicDetail",
            "oe-version-no": "V4.0.0.1",
            "x-track-code": "{}".format(uuid4()),
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36",
            "Referer": self.indexUrl,
            "Accept-Encoding": "gzip, deflate, br",
            "Accept-Language": "zh-CN,zh;q=0.9",
        }
        resInfo = self.resTools.parseUrl(url=url, fileName='partsEngineerSubjects'+cid+groupCode+subjectId)
        partsInfo = json.loads(resInfo.get("content", ""))
        return partsInfo

    def get_tokenData(self, appId, cid, groupCode, subject, suffix):
        url = 'https://dpj.saic-gm.com/epcoloe4dealer/rest/brands/token'
        params = "?appId={}&_dc={}".format(appId, self.get_timeStr())
        url = url + params
        self.resTools.headers = {
            "Host": "dpj.saic-gm.com",
            "Connection": "keep-alive",
            "Pragma": "no-cache",
            "Cache-Control": "no-cache",
            "Accept": "application/json, text/plain, */*",
            "x-resource-code": "catalogsgotoPartPicDetail",
            "oe-version-no": "V4.0.0.1",
            "x-track-code": "{}".format(uuid4()),
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36",
            "Referer": self.indexUrl,
            "Accept-Encoding": "gzip, deflate, br",
            "Accept-Language": "zh-CN,zh;q=0.9",
        }
        resInfo = self.resTools.parseUrl(url=url, fileName='token'+cid+groupCode+subject+suffix)
        tokenInfo = json.loads(resInfo.get("content"))
        return tokenInfo

    def getImg(self, cid, subject, suffix, tokenData):
        mid = subject+suffix
        url = '{}pic_{}.gif'.format(fileDownUrl, mid)
        imgName = mid+url[-4:]
        params = '?token={}'.format(tokenData)
        url = url+params
        cidPath = self.imgPath+os.sep+cid
        if not os.path.exists(cidPath):
            os.makedirs(cidPath)
        imgPath = cidPath+os.sep+imgName
        if not os.path.exists(imgPath):
            self.resTools.headers = {
                "Host": "csapi.saic-gm.com",
                "Connection": "keep-alive",
                "Pragma": "no-cache",
                "Cache-Control": "no-cache",
                "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36",
                "Accept": "image/webp,image/apng,image/*,*/*;q=0.8",
                "Referer": self.indexUrl,
                "Accept-Encoding": "gzip, deflate, br",
                "Accept-Language": "zh-CN,zh;q=0.9",
            }
            cookies = deepcopy(self.resTools.cookies)
            del cookies["JSESSIONID"]
            print("请求图片:", url)
            res = self.resTools.getImg(url=url, cookies=cookies)
            if res:
                with open(imgPath, 'wb') as i:
                    i.write(res.content)
                print("success")


    def getData(self, cars):
        cid = cars.get("catalogCode")
        if cid not in self.cidList:
            return
        name = cars.get("catalogName").split(":")[1]
        cidPath = self.basePath + os.sep + cid
        if not os.path.exists(cidPath):
            os.makedirs(cidPath)
        else:
            pass
        self.resTools.basePath = cidPath
        print("开始抓取: ", cid, name)
        time.sleep(random.randint(1, 3))
        print("请求主组列表: ", cid)
        groupsInfo = self.get_groupInfo(cid)
        for group in groupsInfo:
            groupCode = group.get("groupCode")
            groupName = group.get("groupName").split(":")[1]

            time.sleep(random.randint(1, 3))
            print("请求分组列表: ", cid, groupCode, groupName)
            strucsInfo = self.get_strucInfo(cid, groupCode)
            for struc in strucsInfo:
                subjectId = str(struc.get("id"))
                suffix = struc.get("suffix") if struc.get("suffix") else ""
                if suffix:
                    subject = struc.get("subject").split("@")[0][:0 - int(len(suffix))]
                else:
                    subject = struc.get("subject").split("@")[0]
                time.sleep(random.randint(1, 3))
                print("请求零件列表: ", cid, groupCode, groupName, subject+suffix, )
                partsInfo = self.get_partsInfo(cid, groupCode, subject, subjectId, suffix)

                # 获取图片
                tokenInfo = self.get_tokenData(appId, cid, groupCode, subject, suffix)
                tokenData = tokenInfo.get("tokenData")
                self.getImg(cid, subject, suffix, tokenData)
        print("end...")


    def get_carsList(self):
        # 获取车型列表
        self.modelYears()
        self.grant()
        carsInfo = self._get_carList()
        return carsInfo


    def run(self):
        carsInfo = self.get_carsList()
        for cars in carsInfo:
            self.getData(cars)

def main():
    # 别克cid对照表:
    '''
    CJ1 全新一代凯越
    CP2 英朗
    CP4 昂科威
    CP5 威朗
    CP6 威朗轿跑/GS
    CR1 昂科雷
    CS1 赛欧
    CU1 GL8
    CU2 陆尊
    CU3 GL8 S
    CU4 GL8 ES 豪华商旅车
    CW1 君威
    CW2 君越
    CW3 君越（混合动力）
    EG1 新君威
    EG2 新君越
    EG6 全新一代君越
    EG7 全新一代君威
    S8E 林荫大道
    S8W 荣御
    SJ2 昂科拉
    SK1 全新英朗
    SK3 阅朗
    SK4 GL6
    SR1 VELITE 5
    SV1 全新一代凯越
    '''
    # 凯迪拉克cid对照表:
    '''
    C11 凯迪拉克 ESCALADE
    CA1 凯迪拉克 ATS
    CA2 凯迪拉克 New CTS
    CD3 凯迪拉克 CTS
    CD4 凯迪拉克 CTS Coupe
    CE2 凯迪拉克 SRX
    CK1 凯迪拉克 CT6
    CN1 凯迪拉克 New SRX
    CY1 凯迪拉克 XLR
    EG4 凯迪拉克 XTS
    EG8 凯迪拉克 XT4
    S6D 凯迪拉克 赛威
    SA1 凯迪拉克 ATSL
    SN1 凯迪拉克 XT5
    '''


    # brand = 'buick'  # !!! 品牌  buick, cadillac
    # cidList = ["CJ1", "CP2"]  # !!! 要抓取的车型cid
    brand = 'cadillac'  # !!! 品牌  buick, cadillac
    cidList = ["C11"]  # !!! 要抓取的车型cid
    tools = ScSpider(brand=brand, cidList=cidList)
    tools.run()


if __name__ == '__main__':
    main()